home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / src / cmds / indent / pr_comment.c < prev    next >
Encoding:
C/C++ Source or Header  |  1989-04-06  |  11.2 KB  |  384 lines

  1. /*
  2.  * Copyright (c) 1980 Regents of the University of California.
  3.  * Copyright (c) 1976 Board of Trustees of the University of Illinois.
  4.  * All rights reserved.
  5.  *
  6.  * Redistribution and use in source and binary forms are permitted
  7.  * provided that this notice is preserved and that due credit is given
  8.  * to the University of California at Berkeley and the University of
  9.  * Illinois at Urbana.  The name of either University may not be used
  10.  * to endorse or promote products derived from this software without
  11.  * specific prior written permission. This software is provided
  12.  * ``as is'' without express or implied warranty.
  13.  */
  14.  
  15. #ifndef lint
  16. static char sccsid[] = "@(#)pr_comment.c    5.5 (Berkeley) 3/22/88";
  17. #endif /* not lint */
  18.  
  19. /*
  20.  * NAME:
  21.  *    pr_comment
  22.  *
  23.  * FUNCTION:
  24.  *    This routine takes care of scanning and printing comments.
  25.  *
  26.  * ALGORITHM:
  27.  *    1) Decide where the comment should be aligned, and if lines should
  28.  *       be broken.
  29.  *    2) If lines should not be broken and filled, just copy up to end of
  30.  *       comment.
  31.  *    3) If lines should be filled, then scan thru input_buffer copying
  32.  *       characters to com_buf.  Remember where the last blank, tab, or
  33.  *       newline was.  When line is filled, print up to last blank and 
  34.  *       continue copying.
  35.  *
  36.  * HISTORY:
  37.  *    November 1976    D A Willcox of CAC    Initial coding
  38.  *    12/6/76        D A Willcox of CAC    Modification to handle 
  39.  *                        UNIX-style comments
  40.  *
  41.  */
  42.  
  43. /*
  44.  * this routine processes comments.  It makes an attempt to keep comments
  45.  * from going over the max line length.  If a line is too long, it moves
  46.  * everything from the last blank to the next comment line.  Blanks and
  47.  * tabs from the beginning of the input line are removed 
  48.  */
  49.  
  50. #include "indent_globs.h"
  51.  
  52.  
  53. pr_comment()
  54. {
  55.     int         now_col;    /* column we are in now */
  56.     int         adj_max_col;    /* Adjusted max_col for when we decide to
  57.                  * spill comments over the right margin */
  58.     int         col_1_com;    /* this comment should not be touched */
  59.     char       *last_bl;    /* points to the last blank in the output
  60.                  * buffer */
  61.     char        achar;
  62.     char       *t_ptr;        /* used for moving string */
  63.     int         unix_comment;    /* tri-state variable used to decide if it
  64.                  * is a unix-style comment. 0 means only
  65.                  * blanks since /*, 1 means regular style
  66.                  * comment, 2 means unix style comment */
  67.     int         break_delim = comment_delimiter_on_blankline;
  68.     int        l_just_saw_decl = ps.just_saw_decl;
  69.     /*
  70.      * int         ps.last_nl = 0;    /* true iff the last significant
  71.      * thing weve seen is a newline 
  72.      */
  73.     int         one_liner = 1;    /* true iff this comment is a one-liner */
  74.     adj_max_col = max_col;
  75.     ps.just_saw_decl = 0;
  76.     last_bl = 0;        /* no blanks found so far */
  77.     ps.box_com = col_1_com = false;    /* at first, assume that we are
  78.                      * not in a boxed comment or some
  79.                      * other comment that should not
  80.                      * be touched */
  81.     ++ps.out_coms;        /* keep track of number of comments */
  82.     unix_comment = 1;        /* set flag to let us figure out if there
  83.                  * is a unix-style comment ** DISABLED:
  84.                  * use 0 to reenable this hack! */
  85.  
  86.     /* Figure where to align and how to treat the comment */
  87.  
  88.     if (ps.col_1 && !format_col1_comments) {    /* if comment starts in
  89.                          * column 1 it should not
  90.                          * be touched */
  91.     col_1_com = ps.box_com = true;
  92.     ps.com_col = 1;
  93.     } else {
  94.     if (*buf_ptr == '-' || *buf_ptr == '*') {
  95.         ps.box_com = true;    /* a comment with a '-' or '*' immediately
  96.                  * after the /* is assumed to be a boxed
  97.                  * comment */
  98.         col_1_com = true;
  99.         break_delim = 0;
  100.     }
  101.     if ( /* ps.bl_line && */ (s_lab == e_lab) && (s_code == e_code)) {
  102.         /* klg: check only if this line is blank */
  103.         /*
  104.          * If this (*and previous lines are*) blank, dont put comment
  105.          * way out at left 
  106.          */
  107.         ps.com_col = (ps.ind_level - ps.unindent_displace) * ps.ind_size + 1;
  108.         adj_max_col = block_comment_max_col;
  109.         if (ps.com_col <= 1)
  110.         ps.com_col = 1 + !format_col1_comments;
  111.     } else {
  112.         register    target_col;
  113.         break_delim = 0;
  114.         if (s_code != e_code)
  115.         target_col = count_spaces(compute_code_target(), s_code);
  116.         else {
  117.         target_col = 1;
  118.         if (s_lab != e_lab)
  119.             target_col = count_spaces(compute_label_target(), s_lab);
  120.         }
  121.         ps.com_col = ps.decl_on_line || ps.ind_level == 0 ? ps.decl_com_ind : ps.com_ind;
  122.         if (ps.com_col < target_col)
  123.         ps.com_col = ((target_col + 7) & ~7) + 1;
  124.         if (ps.com_col + 24 > adj_max_col)
  125.         adj_max_col = ps.com_col + 24;
  126.     }
  127.     }
  128.     if (ps.box_com) {
  129.     buf_ptr[-2] = 0;
  130.     ps.n_comment_delta = 1 - count_spaces(1, in_buffer);
  131.     ps.comment_delta = 0;
  132.     buf_ptr[-2] = '/';
  133.     } else {
  134.     ps.n_comment_delta = 0;
  135.     ps.comment_delta = 0;
  136.     while (*buf_ptr == ' ' || *buf_ptr == '\t')
  137.         buf_ptr++;
  138.     }
  139.     ps.comment_delta = 0;
  140.     *e_com++ = '/';        /* put '/*' into buffer */
  141.     *e_com++ = '*';
  142.     if (*buf_ptr != ' ' && !ps.box_com)
  143.     *e_com++ = ' ';
  144.  
  145.     *e_com = '\0';
  146.     now_col = count_spaces(ps.com_col, s_com);    /* figure what column we
  147.                          * would be in if we
  148.                          * printed the comment now */
  149.  
  150.     /* Start to copy the comment */
  151.  
  152.     while (1) {            /* this loop will go until the comment is
  153.                  * copied */
  154.     if (*buf_ptr > 040 && *buf_ptr != '*')
  155.         ps.last_nl = 0;
  156.     switch (*buf_ptr) {    /* this checks for various spcl cases */
  157.         case 014:        /* check for a form feed */
  158.         if (!ps.box_com) {    /* in a text comment, break the
  159.                      * line here */
  160.             ps.use_ff = true;
  161.             /* fix so dump_line uses a form feed */
  162.             dump_line();
  163.             last_bl = 0;
  164.             *e_com++ = ' ';
  165.             *e_com++ = '*';
  166.             *e_com++ = ' ';
  167.             while (*++buf_ptr == ' ' || *buf_ptr == '\t');
  168.         } else {
  169.             if (++buf_ptr >= buf_end)
  170.             fill_buffer();
  171.             *e_com++ = 014;
  172.         }
  173.         break;
  174.  
  175.         case '\n':
  176.         if (had_eof) {    /* check for unexpected eof */
  177.             printf("Unterminated comment\n");
  178.             *e_com = '\0';
  179.             dump_line();
  180.             return;
  181.         }
  182.         one_liner = 0;
  183.         if (ps.box_com || ps.last_nl) {    /* if this is a boxed
  184.                          * comment, we dont ignore
  185.                          * the newline */
  186.             if (s_com == e_com) {
  187.             *e_com++ = ' ';
  188.             *e_com++ = ' ';
  189.             }
  190.             *e_com = '\0';
  191.             if (!ps.box_com && e_com - s_com > 3) {
  192.             if (break_delim == 1 && s_com[0] == '/'
  193.                 && s_com[1] == '*' && s_com[2] == ' ') {
  194.                 char       *t = e_com;
  195.                 break_delim = 2;
  196.                 e_com = s_com + 2;
  197.                 *e_com = 0;
  198.                 if (blanklines_before_blockcomments) prefix_blankline_requested = 1;
  199.                 dump_line();
  200.                 e_com = t;
  201.                 s_com[0] = s_com[1] = s_com[2] = ' ';
  202.             }
  203.             dump_line();
  204.             *e_com++ = ' ';
  205.             *e_com++ = ' ';
  206.             }
  207.             dump_line();
  208.             now_col = ps.com_col;
  209.         } else {
  210.         ps.last_nl = 1;
  211.         if (unix_comment != 1) {    /* we not are in
  212.                          * unix_style comment */
  213.             if (unix_comment == 0 && s_code == e_code) {
  214.             /*
  215.              * if it is a UNIX-style comment, ignore the
  216.              * requirement that previous line be blank for
  217.              * unindention 
  218.              */
  219.             ps.com_col = (ps.ind_level - ps.unindent_displace) * ps.ind_size + 1;
  220.             if (ps.com_col <= 1)
  221.                 ps.com_col = 2;
  222.             }
  223.             unix_comment = 2;    /* permanently remember that we
  224.                      * are in this type of comment */
  225.             dump_line();
  226.             ++line_no;
  227.             now_col = ps.com_col;
  228.             *e_com++ = ' ';
  229.             /*
  230.              * fix so that the star at the start of the line will
  231.              * line up 
  232.              */
  233.             do        /* flush leading white space */
  234.             if (++buf_ptr >= buf_end)
  235.                 fill_buffer();
  236.             while (*buf_ptr == ' ' || *buf_ptr == '\t');
  237.             break;
  238.         }
  239.         if (*(e_com - 1) == ' ' || *(e_com - 1) == '\t')
  240.             last_bl = e_com - 1;
  241.         /*
  242.          * if there was a space at the end of the last line,
  243.          * remember where it was 
  244.          */
  245.         else {        /* otherwise, insert one */
  246.             last_bl = e_com;
  247.             *e_com++ = ' ';
  248.             ++now_col;
  249.         }
  250.         }
  251.         ++line_no;    /* keep track of input line number */
  252.         if (!ps.box_com) {
  253.             int         nstar = 1;
  254.             do {    /* flush any blanks and/or tabs at start
  255.                  * of next line */
  256.             if (++buf_ptr >= buf_end)
  257.                 fill_buffer();
  258.             if (*buf_ptr == '*' && --nstar >= 0) {
  259.                 if (++buf_ptr >= buf_end)
  260.                 fill_buffer();
  261.                 if (*buf_ptr == '/')
  262.                 goto end_of_comment;
  263.             }
  264.             } while (*buf_ptr == ' ' || *buf_ptr == '\t');
  265.         } else if (++buf_ptr >= buf_end) fill_buffer();
  266.         break;        /* end of case for newline */
  267.  
  268.         case '*':        /* must check for possibility of being at
  269.                  * end of comment */
  270.         if (++buf_ptr >= buf_end)    /* get to next char after * */
  271.             fill_buffer();
  272.  
  273.         if (unix_comment == 0)    /* set flag to show we are not in
  274.                      * unix-style comment */
  275.             unix_comment = 1;
  276.  
  277.         if (*buf_ptr == '/') {    /* it is the end!!! */
  278.         end_of_comment:
  279.             if (++buf_ptr >= buf_end)
  280.             fill_buffer();
  281.  
  282.             if (*(e_com - 1) != ' ' && !ps.box_com) {    /* insure blank before
  283.                                  * end */
  284.             *e_com++ = ' ';
  285.             ++now_col;
  286.             }
  287.             if (break_delim == 1 && !one_liner && s_com[0] == '/'
  288.             && s_com[1] == '*' && s_com[2] == ' ') {
  289.             char       *t = e_com;
  290.             break_delim = 2;
  291.             e_com = s_com + 2;
  292.             *e_com = 0;
  293.                 if (blanklines_before_blockcomments) prefix_blankline_requested = 1;
  294.             dump_line();
  295.             e_com = t;
  296.             s_com[0] = s_com[1] = s_com[2] = ' ';
  297.             }
  298.             if (break_delim == 2 && e_com > s_com + 3
  299.              /* now_col > adj_max_col - 2 && !ps.box_com */ ) {
  300.             *e_com = '\0';
  301.             dump_line();
  302.             now_col = ps.com_col;
  303.             }
  304.             *e_com++ = '*';
  305.             *e_com++ = '/';
  306.             *e_com = '\0';
  307.             ps.just_saw_decl = l_just_saw_decl;
  308.             return;
  309.         } else {    /* handle isolated '*' */
  310.             *e_com++ = '*';
  311.             ++now_col;
  312.         }
  313.         break;
  314.         default:        /* we have a random char */
  315.         if (unix_comment == 0 && *buf_ptr != ' ' && *buf_ptr != '\t')
  316.             unix_comment = 1;    /* we are not in unix-style
  317.                      * comment */
  318.  
  319.         *e_com = *buf_ptr++;
  320.         if (buf_ptr >= buf_end)
  321.             fill_buffer();
  322.  
  323.         if (*e_com == '\t')    /* keep track of column */
  324.             now_col = ((now_col - 1) & tabmask) + tabsize + 1;
  325.         else if (*e_com == '\b')    /* this is a backspace */
  326.             --now_col;
  327.         else
  328.             ++now_col;
  329.  
  330.         if (*e_com == ' ' || *e_com == '\t')
  331.             last_bl = e_com;
  332.         /* remember we saw a blank */
  333.  
  334.         ++e_com;
  335.         if (now_col > adj_max_col && !ps.box_com && unix_comment == 1 && e_com[-1] > ' ') {
  336.             /* the comment is too long, it must be broken up */
  337.             if (break_delim == 1 && s_com[0] == '/'
  338.             && s_com[1] == '*' && s_com[2] == ' ') {
  339.             char       *t = e_com;
  340.             break_delim = 2;
  341.             e_com = s_com + 2;
  342.             *e_com = 0;
  343.                 if (blanklines_before_blockcomments) prefix_blankline_requested = 1;
  344.             dump_line();
  345.             e_com = t;
  346.             s_com[0] = s_com[1] = s_com[2] = ' ';
  347.             }
  348.             if (last_bl == 0) {    /* we have seen no blanks */
  349.             last_bl = e_com;    /* fake it */
  350.             *e_com++ = ' ';
  351.             }
  352.             *e_com = '\0';    /* print what we have */
  353.             *last_bl = '\0';
  354.             while (last_bl > s_com && last_bl[-1] < 040)
  355.             *--last_bl = 0;
  356.             e_com = last_bl;
  357.             dump_line();
  358.  
  359.             *e_com++ = ' ';    /* add blanks for continuation */
  360.             *e_com++ = ' ';
  361.             *e_com++ = ' ';
  362.  
  363.             t_ptr = last_bl + 1;
  364.             last_bl = 0;
  365.             if (t_ptr >= e_com) {
  366.             while (*t_ptr == ' ' || *t_ptr == '\t')
  367.                 t_ptr++;
  368.             while (*t_ptr != '\0') {    /* move unprinted part
  369.                              * of comment down in
  370.                              * buffer */
  371.                 if (*t_ptr == ' ' || *t_ptr == '\t')
  372.                 last_bl = e_com;
  373.                 *e_com++ = *t_ptr++;
  374.             }
  375.             }
  376.             *e_com = '\0';
  377.             now_col = count_spaces(ps.com_col, s_com);    /* recompute current
  378.                                  * position */
  379.         }
  380.         break;
  381.     }
  382.     }
  383. }
  384.